package com.gpStudy.thread;

import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockConditionTest {

    private LinkedList<String> product = new LinkedList<>();

    private AtomicInteger inventory = new AtomicInteger(0);// 实时库存

    private int maxInventory = 10;// 最大库存

//    private Lock lock = new ReentrantLock();// 资源锁
//    private Condition condition = lock.newCondition();

    private Lock consumerLock = new ReentrantLock();// 资源锁-消费
    private Lock productLock = new ReentrantLock();// 资源锁-生产

    private Condition notEmptyCondition = consumerLock.newCondition();// 库存满和空条件
    private Condition notFullCondition = productLock.newCondition();// 库存满和空条件


    /**
     * 新增商品库存
     * @param e
     */
    public void produce(String e){
        productLock.lock();
        try {
            while (inventory.get() == maxInventory){
                notFullCondition.await();
            }
            product.add(e);
            System.out.println("放入一个商品库存，总库存为：" + inventory.incrementAndGet());
            if (inventory.get() < maxInventory) {
                notFullCondition.signalAll();
            }
//            condition.signalAll();
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        } finally {
//            lock.unlock();
            productLock.unlock();
        }

        if (inventory.get() > 0) {
            try {
                consumerLock.lockInterruptibly();
                notEmptyCondition.signalAll();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            } finally {
                consumerLock.unlock();
            }
        }
    }

    /**
     *  消费商品
     * @return
     */
    public String consume(){

        String result = null;
//        lock.lock();
        consumerLock.lock();
        try {
            while (product.size() == 0){
//                condition.await();
                notEmptyCondition.await();
            }
            result = product.removeLast();
            System.out.println(" 消费一个商品，库存为" + inventory.decrementAndGet());
            if (inventory.get() > 0) {
                notEmptyCondition.signalAll();
            }
//            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
//            lock.unlock();
            consumerLock.unlock();
        }
        if (inventory.get() < maxInventory) {

            try {
                productLock.lockInterruptibly();
                notFullCondition.signalAll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                productLock.unlock();
            }
        }
        return result;
    }

    private class Producer implements Runnable{

        public void run(){
            for (int i=0; i < 20; i++){
                produce(" 商品 " + i);
            }
        }
    }

    private class Customer implements Runnable{

        public void run(){
            for (int i = 0; i < 20; i++) {
                consume();
            }
        }
    }

    public static void main(String[] args) {
        LockConditionTest lc = new LockConditionTest();
        new Thread(lc.new Producer()).start();
        new Thread(lc.new Customer()).start();
        new Thread(lc.new Producer()).start();
        new Thread(lc.new Customer()).start();
    }

}
